﻿module Sustainalytics.EsgRatings {

    export class EsgRpIndicatorsController {

        private esgCtrl: EsgController;
        private indicatorsSkipOverwriting: boolean = false;

        public indicatorClusters: EsgRpIndicatorClusterDto[];
        public selectedIndicatorCluster: EsgRpIndicatorClusterDto;

        public indicators: EsgRpIndicatorDto[] = [];
        public indicatorsSkip: number = 0;
        public indicatorsTake: number = 5;
        public lastGetData: any;
        public resetScrollPager: boolean = false;
        public scrollPagerLocked: boolean = true;
       // public showLoader:boolean=false;
        private userId: string;
        private esgProfileId: string;

        public notFound: boolean = false;
        public noClaims: boolean = false;

        constructor(
            private $scope: IEsgThemeScope,
            private $location: ng.ILocationService, 
            private $anchorScroll: any, 
            private $q: ng.IQService,
            private $timeout: ng.ITimeoutService,
            private EsgRpIndicatorClusterService: IEsgRpIndicatorClusterService,
            private EsgRpIndicatorService: IEsgRpIndicatorService,
            private $rootScope,
            private staticObjects: Common.IStaticObjects) {

            var ctx = this;

            if (ctx.$rootScope['userInfo'] == null) {
                ctx.$rootScope['userInfo'] = angular.fromJson(localStorage.getItem('sust_userInfo'));
            }
            ctx.userId = ctx.$rootScope['userInfo'].userId;
            ctx.esgProfileId = ctx.$rootScope['userInfo'].esgProfileId;

            // get ESG Controller from scope
            ctx.esgCtrl = $scope['esg'];

            $scope['esgRpIndicators'] = ctx;            

            ctx.init();
        }


        private init(): ng.IPromise<any> {

            var ctx = this;

            var def = ctx.$q.defer();

            //ctx.scrollPagerLocked = true;
            ctx.scrollPagerLocked = !ctx.esgCtrl.hasFocusRatings;


            if (!ctx.esgCtrl.hasFocusRatings) {
                // get indicators clusters
                ctx.getIndicatorClusters().then(
                    // success
                    () => {

                        // get indicators for default cluster
                        this.getIndicators().then(
                            // success
                            () => {
                                //ctx.scrollPagerLocked = false;
                                def.resolve();
                            },
                            // error
                            () => {
                                //ctx.scrollPagerLocked = false;
                                def.reject();
                            });
                    },
                    // error
                    () => {
                        def.reject();
                    });
            } else {
                this.getIndicators().then(
                    // success
                    () => {
                        //ctx.scrollPagerLocked = false;
                        def.resolve();
                    },
                    // error
                    () => {
                        //ctx.scrollPagerLocked = false;
                        def.reject();
                    });
            }

            // refresh on page changed
            function onPageChange() {
                if (ctx.indicatorsSkipOverwriting) {
                    ctx.indicatorsSkipOverwriting = false;
                } else {
                    ctx.getIndicators();
                }
            };

            if (!ctx.esgCtrl.hasFocusRatings) {
                // listen for scroll changes
                ctx.$scope.$watch('esgRpInd.indicatorsSkip', onPageChange);
                ctx.$scope.$watch('esgRpInd.indicatorsTake', onPageChange);
            }
            return def.promise;
        }

        private getIndicatorClusters(): ng.IPromise<any> {
            var ctx = this;

            var currentTheme = ctx.$scope.currentTheme;
            // get indicators clusters
            var indicatorClustersPromise = ctx.EsgRpIndicatorClusterService.get(currentTheme).then(
                // success
                function (indicatorClusters) {

                    // set indicator clusters
                    ctx.indicatorClusters = indicatorClusters;
                    
                    ctx.selectedIndicatorCluster = null;

                    if (ctx.indicatorClusters && ctx.indicatorClusters.length > 0) {
                        if (ctx.esgCtrl.selectedIndicator) {
                            for (var i = 0; i < ctx.indicatorClusters.length; i++) {
                                var cluster = ctx.indicatorClusters[i];

                                if (parseInt(cluster.id) == ctx.esgCtrl.selectedIndicator.indicatorCategoryId) {
                                    ctx.selectedIndicatorCluster = cluster;
                                    break;
                                }
                            }
                        }
                        else {
                            ctx.selectedIndicatorCluster = ctx.indicatorClusters[0];// use first indicator as the default indicator cluster   
                        }                        
                    }

                    ctx.$timeout(function () {
                        ctx.$scope.$apply();
                    });
                },() => {
                    ga('create', 'UA-4379897-6', {
                        'userId': ctx.userId, 'cookieDomain': 'none', 'name': 'globalAccess'
                    });

                    ga('globalAccess.send', 'exception', { 'exDescription': 'Esg Ratings: Rp Indicators Controller -> Error loading Indicator Clusters' });
                });

            return indicatorClustersPromise;
        }

        private getIndicators(): ng.IPromise<any> {
            var ctx = this;
            
            if (!ctx.$scope.currentCompany || !ctx.$scope.currentTheme || (!ctx.selectedIndicatorCluster && !ctx.esgCtrl.hasFocusRatings)) {
                return ctx.$q.when(null);
            }

            var getData =
                {
                    companyId: ctx.$scope.currentCompany.id,
                    esgProfileId: ctx.esgProfileId,
                    clusterName: ctx.esgCtrl.hasFocusRatings ? "" : ctx.selectedIndicatorCluster.name,
                    theme: ctx.$scope.currentTheme,
                    skip: ctx.indicatorsSkip,
                    take: ctx.indicatorsTake, 
                    indicatorNumber: ctx.esgCtrl.selectedIndicator ? ctx.esgCtrl.selectedIndicator.id : null
                };

            if (ctx.lastGetData && angular.equals(ctx.lastGetData, getData)) {
                return ctx.$q.when(null);
            }

            ctx.lastGetData = getData;
            ctx.$rootScope['loading'] = true;
            //ctx.showLoader = true;

            var indicatorsPromise = ctx.EsgRpIndicatorService.get(
                getData.companyId,
                getData.esgProfileId,
                getData.clusterName,
                getData.theme,
                getData.skip,
                getData.take,
                getData.indicatorNumber);


            indicatorsPromise.then(
                // success
                function (indicators) {
                    ctx.$rootScope['loading'] = false;
                    //ctx.showLoader = false;
                    if (!indicators) {
                        return;
                    }

                    if (indicators.length > ctx.indicatorsTake) {
                        ctx.indicatorsSkipOverwriting = true;

                        var remainder = indicators.length % ctx.indicatorsTake;
                        ctx.indicatorsSkip = indicators.length - (remainder ? remainder : ctx.indicatorsTake);
                    }

                    // set indicators
                    ctx.indicators.push.apply(ctx.indicators, indicators);

                    // handle each indicator
                    $.each(ctx.indicators, function (index, ind) {
                        // associate a structure to each indicator so that all indicators values are grouped by indicator name and then ordered by year
                        ctx.groupNonRatedIndicatorsByName(ind);
                    });
                    
                    if (ctx.esgCtrl.selectedIndicator) {
                        ctx.scrollPagerLocked = true;
                        ctx.$anchorScroll.yOffset = $("#top-wrap-scroll").height();
                        ctx.$location.hash(ctx.esgCtrl.selectedIndicator.id);
                        
                        ctx.esgCtrl.selectedIndicator = null;// the navigation source needs to be reset
                    }

                    ctx.$timeout(() => {
                        ctx.$scope.$apply();
                        ctx.$timeout(() => ctx.scrollPagerLocked = false, 500);// reactivate scrollPager; please inform the team in case you find a smarter way to do it without triggering a "new page event"
                    });
                },(reason) => {
                    ctx.esgCtrl.selectedIndicator = null;// the eventual navigation source needs to be reset

                    ctx.$rootScope['loading'] = false;
                    //ctx.showLoader = false;
                    if (reason.status == 404 || reason.staus == 204) {

                        if (reason.data.errCode !== null) {
                            ctx.notFound =true;
                        }
                    }

                    if (reason.status == 401) {
                        ctx.noClaims = true;
                    }

                    ga('create', 'UA-4379897-6', {
                        'userId': ctx.userId, 'cookieDomain': 'none', 'name': 'globalAccess'
                    });

                    ga('globalAccess.send', 'exception', { 'exDescription': 'Esg Ratings: Rp Indicators Controller -> Error retrieving indicators' });
                });

            return indicatorsPromise;
        }
        private goToTop() {
            $("html, body").animate({
                scrollTop: $("#moduleLoaderProgress").prop("clientHeight") - 50
            }, 500);
        }
        private groupNonRatedIndicatorsByName(ind: EsgRpIndicatorDto) {
            var ctx = this;

            if (!ind || !ind.dataTable || ind.dataTable.length == 0)
                return;

            
            var minYear = 99999;
            var maxYear = 0;

            // get min and max year
            ind.dataTable.forEach(function (nonRatedInd) {
                if (nonRatedInd.year < minYear)
                    minYear = nonRatedInd.year;

                if (maxYear < nonRatedInd.year)
                    maxYear = nonRatedInd.year;
            });


            
            var nonRatedIndByName = new Common.Dictionary<Common.Dictionary<EsgRpNonRatedIndicatorValueDto>>();

            // non rated indicators values grouped by name and ordered by year
            ind.dataTable.forEach(function (nonRatedInd) {

                var nonRatedIndValues: Common.Dictionary<EsgRpNonRatedIndicatorValueDto>;

                if (nonRatedIndByName.containsKey(nonRatedInd.name)) {
                    nonRatedIndValues = nonRatedIndByName.getValue(nonRatedInd.name);
                }
                else {
                    nonRatedIndValues = new Common.Dictionary<EsgRpNonRatedIndicatorValueDto>();

                    // add dictionary of values ordered by year
                    nonRatedIndByName.add(nonRatedInd.name, nonRatedIndValues);

                    // add years to dictionary
                    for (var year = minYear; year <= maxYear; year++) {
                        nonRatedIndValues.add(year.toString(), { name: nonRatedInd.name, year: year, value: null });
                    }
                }

                // set indicator value
                var dicNonRatedInd = nonRatedIndValues.getValue(nonRatedInd.year.toString());
                $.extend(dicNonRatedInd, nonRatedInd, true);
            });


            // arrange dictionary into an array
            var nonRatedIndList = $.map(nonRatedIndByName.getItems(), function (nonRatedIndValues) {

                // create non rated indicator holding all its values
                var nonRatedInd = new EsgRpNonRatedIndicator(nonRatedIndValues.key, nonRatedIndValues.value.getValues().reverse());
                return nonRatedInd;
            });


            ind.dataTableByName = nonRatedIndList;

            // add non rated years
            ind.dataTableYears = [];
            for (var year = maxYear; year >= minYear; year--) {
                ind.dataTableYears.push(year);
            }
        }

        private selectIndicatorCluster(indicatorCluster: EsgRpIndicatorClusterDto) {
            var ctx = this;

            ctx.$location.hash("");

            ctx.scrollPagerLocked = true;

            //return if the same tab is clicked
            if (ctx.selectedIndicatorCluster.id == indicatorCluster.id)
                return;

            // remove items
            ctx.indicators = [];

            // set indicator cluster
            ctx.selectedIndicatorCluster = indicatorCluster;

            // reset paging
            ctx.resetScrollPager = true;
            ctx.indicatorsSkip = 0;

            // get indicator cluster indicators
            var indicatorsPromise = ctx.getIndicators();

            indicatorsPromise.then(function () {
                ctx.scrollPagerLocked = false;
            });

            ctx.$timeout(function () {
                ctx.$scope.$apply();
            });
        }
    }


    export var esgRpIndicatorsControllerName = 'EsgRpIndicatorsController';

    angular.module(esgRatingsModuleName).controller(esgRpIndicatorsControllerName,
        ['$scope', '$location', '$anchorScroll', '$q', '$timeout', 'EsgRpIndicatorClusterService', 'EsgRpIndicatorService', '$rootScope', 'staticObjects', EsgRpIndicatorsController]);
}